<template>
  <el-dialog :width="option.dialogWidth || '600px'" v-model="isVisible" @close="onCancelModel" append-to-body>
    <template #header="{ close, titleId, titleClass }">
      <span :id="titleId" :class="titleClass">{{originData?.id ? '编辑':'新建'}}{{option.businessName}}</span>
    </template>
    <div class="yy-user-model_content">
      <div style="padding-right: 80px;">
        <WidgetForm ref="formDialogRef" :form-fields="formFields" />
      </div>
    </div>
    <template #footer>
        <span class="dialog-footer">
          <el-button @click="onCancelModel">关闭</el-button>
          <el-button type="primary" :loading="isLoading" @click="onSave">保存</el-button>
        </span>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import {defineEmits, defineExpose, defineProps, nextTick, reactive, ref, watch} from 'vue'
import {ElMessage, FormInstance, FormRules} from "element-plus";
import {BaseModel} from "@/model/BaseModel";
import WidgetForm from "@/components/widget/WidgetForm.vue";


const props = defineProps({
  option: {
    type: Object,
    required: false,
    default: Object.assign({})
  },
  formFields: {
    type: Array,
    required: true,
    default: () => []
  },
  modelInstance: {
    type: BaseModel,
    required: true,
    default: () => null
  },
  saveApiFun: {
    type: Function,
    required: true,
    default: () => null
  },
  updateApiFun: {
    type: Function,
    required: true,
    default: () => null
  }
})

const isVisible = ref(false)
const isLoading = ref(false)
const formDialogRef = ref()

const originData = ref<Record<string, any>>()

// 当前form表单验证规则
const rules = reactive<FormRules>({})

const $emit = defineEmits({
  editCallback: ((data: BaseModel) => data),
})

const onShowDialog = (data: Record<string, any>) => {
  isVisible.value = true
  if (data) {
    originData.value = data
  }
  nextTick(() => {
    formDialogRef.value?.initFormData(data)
  })
}

const onCancelModel = () => {
  originData.value = null
  if (isVisible.value) {
    setTimeout(() => {
      formDialogRef.value.resetFields()
    }, 200)
  }
  isVisible.value = false
}

const getFormFieldValue = () => {
  let modelProperty = {
    id: originData.value ? originData.value.id : undefined
  }
  const formFieldProperty = formDialogRef.value.getFormFieldValue()
  modelProperty = Object.assign({}, modelProperty, formFieldProperty)
  return modelProperty;
}


const setFieldValue = (field: string, val: any) => {
  nextTick(() => {
    formDialogRef.value.setFieldValue(field, val)
  })
}

const showOrHideField = (field: string, isHide: boolean) => {
  nextTick(() => {
    formDialogRef.value?.showOrHideField(field, isHide)
  })

}

const onSave = () => {
  formDialogRef.value.validateForm((valid, fields) => {
    if (valid) {
      let modelProperty = {
        id: originData.value ? originData.value.id : undefined
      }
      const formFieldProperty = formDialogRef.value.getFormFieldValue()
      modelProperty = Object.assign({}, modelProperty, formFieldProperty)

      const modelData = props.modelInstance.deserialize(modelProperty)
      isLoading.value = true
      if (originData.value?.id) {
        console.log('on update data:::', modelData)
         props.updateApiFun(originData.value.id, modelData).then(() => {
           originData.value.deserialize(Object.assign({}, modelProperty, {
             updateTime: new Date()
           }))
           ElMessage.success({
             message: '记录更新成功',
             showClose: true
           })
           $emit('editCallback', originData.value)
           isLoading.value = false
           onCancelModel()
         }, () => {
           isLoading.value = false
         })
      } else {
        console.log('on save data:::', modelData)
        props.saveApiFun(modelData).then((res) => {
          onCancelModel()
          ElMessage.success({
            message: '记录新建成功',
            showClose: true
          })
          if (modelData.hasOwnProperty("updateTime")) {
            modelData.updateTime = new Date()
          }
          $emit('editCallback', res)
          isLoading.value = false
        }, () => {
          isLoading.value = false
        })
      }
    }
  })
}

defineExpose({
  onShowDialog,
  setFieldValue,
  getFormFieldValue,
  showOrHideField
})
</script>